package cn.com.ccxe.input;

import java.sql.ResultSet;
import java.util.List;

import cn.com.ccxe.core.entity.Keyword;
import cn.com.ccxe.core.entity.MonitorType;
import cn.com.ccxe.core.entity.Website;

import com.ccxe.manage.db.CcxDB;
import com.ccxe.manage.db.DBFactory;

public class SaveData {
	
	private CcxDB 			db;					
	private Reader			reader;				//XML读取器
	private int 			resultCount = 0;	//数据库执行计数器
	
	public SaveData(CcxDB db) {
		this.db = db;
	}
	/**
	 * 导入{@link MonitorType}
	 * @throws Exception 如果执行数据库操作出现任何异常，就会 抛出该异常，并进行回滚操作。
	 */
	public void saveMonitorType() throws Exception{
		List<MonitorType> list = reader.readMonitorType();
		for (MonitorType monitorType : list) {
			addMonitorType(monitorType);
		}
	}
	
	/**
	 * 导入{@link Keyword}
	 * @throws Exception 如果执行数据库操作出现任何异常，就会 抛出该异常，并进行回滚操作。
	 */
	public void saveKeyword() throws Exception{
		List<Keyword> list = reader.readKeyword();
		for (Keyword keyword : list) {
			addKeyword(keyword);
		}
	}
	
	/**
	 * 导入{@link Website}
	 * @throws Exception 如果执行数据库操作出现任何异常，就会 抛出该异常，并进行回滚操作。
	 */
	public void saveWebsite() throws Exception {
		List<Website> list = reader.readWebsite();
		for (Website website : list) {
			int id = addWebsiteAndRetuenId(website);
			website.setId(id);
			recursionSaveWebsite(website);
		}
	}
	public void setRead(Reader read) {
		this.reader = read;
	}
	/**
	 * 迭代导入{@link Website}
	 * @throws Exception 如果执行数据库操作出现任何异常，就会 抛出该异常，并进行回滚操作。
	 */
	private void recursionSaveWebsite(Website parent) throws Exception {
		List<Website> children = parent.getChildren();
		if(children!= null && children.size() > 0) {
			for (Website child : children) {
				child.setParentId(parent.getId());
				int id = addWebsiteAndRetuenId(child);
				child.setId(id);
				recursionSaveWebsite(child);
			}
		}
	}
	
	/**
	 * 只获取{@link ResultSet}的第一个列
	 * @param sql
	 * @param parameters
	 * @return
	 * @throws Exception 
	 */
	protected int queryInt(String sql, Object[] parameters) throws Exception {
		ResultSet rs = null;
		rs = db.executeQuery(sql,parameters);
		if(rs.next()) {
			int temp = rs.getInt(1);
			return temp;
		} else {
			throw new Exception("错误！");
		}
	}
	/**
	 * 进行事务管理
	 * 
	 * @param sql
	 * @param parametes
	 * @return
	 * @throws Exception 
	 */
	private void execute(String sql, Object[] parametes) throws Exception {
		System.out.println("SQL:"+sql);
		StringBuilder sb = new StringBuilder("参数为:");
		for (Object object : parametes) {
			sb.append(object).append(",");
		}
		System.out.println(sb.toString());
		int r = db.executeUpdate(sql, parametes);
		if(r <= 0 ) {
			throw new Exception("操作失败！");
		}
		resultCount ++;
	}
	
	
	private void addMonitorType(MonitorType monitorType) throws Exception {
		String sql = "INSERT INTO C_MONITOR_TYPE(ID,TYPE,ISSTART) " +
				" VALUES(SEQ_C_MONITOR_TYPE.NEXTVAL,?,?)";
		
		Object [] objs = new Object[]{
				monitorType.getType(),
				monitorType.getIsStart()};
		execute(sql, objs);
	}
	
	private void addKeyword(Keyword keyword) throws Exception {
		String sql = "INSERT INTO C_KEYWORD(ID,TEXT) "
				+ "VALUES(SEQ_C_KEYWORD.NEXTVAL,?)";
		
		execute(sql, new Object[] { keyword.getText() });
	}
	
	private int addWebsiteAndRetuenId(Website module) throws Exception {
		int id = queryInt("SELECT SEQ_C_MODULE.NEXTVAL FROM DUAL",null);
		String sql = 
				" INSERT INTO C_MODULE " +
					" (ID, NAME, PARENT_ID, DISCRIPTION, PATH, IS_LIST, IS_MONITOR) "+
					" VALUES (?,?,?,?,?,?,?) ";
		Object[] parameters = new Object[] {
			id,
			module.getName(),
			module.getParentId(),
			module.getDiscription(),
			module.getPath(),
			module.getIsList(),
			module.getIsMonitor()
		};
		execute(sql, parameters);
		return id;
	}
	
	/**
	 * 开始事务
	 */
	private void beginTransaction() {
		try {
			db.setAutoCommit(false);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 提交
	 * 
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	private void commit() throws Exception {
		if (db == null) {
			throw new NullPointerException("数据库实例为空或没有获取，无法提交事务！");
		}
		db.commit();
	}

	/**
	 * 执行回滚操作
	 * 
	 * @param ccxDB
	 */
	private void rollback() {
		try {
			db.rollback();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		CcxDB db;
		SaveData saveData = null;
		
		try {
			db = DBFactory.getInstance();
			saveData = new SaveData(db);
			Reader r = new TextReader();
			saveData.setRead(r);
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			saveData.beginTransaction();
//			saveData.saveMonitorType();
			saveData.saveKeyword();
//			saveData.saveWebsite();
			System.out.println("===========数据全部添加完成！===============");
//			throw new Exception("测试异常！！！");
			saveData.commit();
		} catch (Exception e) {
			System.out.println("导入数据异常，请检查");
		} finally {
			saveData.rollback();
		}
	}
}
